package com.anjian.action;

import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.logging.Level;
import java.util.logging.Logger;

import com.anjian.taobao.TaobaoProxy;
import com.anjian.utils.PagingResult;
import com.opensymphony.xwork2.ActionContext;
import com.taobao.api.ApiException;
import com.taobao.api.domain.Item;
import com.taobao.api.response.ItemUpdateResponse;
import com.taobao.api.response.ItemsInventoryGetResponse;
import com.taobao.api.response.ItemsOnsaleGetResponse;

public class DetectPageAction extends ActionBase {

static Logger _log = Logger.getLogger(DetectAction.class.getName());
	
	public static final int SCOPE_ONSALE = 0;
	public static final int SCOPE_INVENTORY = 1;

	private int scope = SCOPE_ONSALE;
	private int pageNo;
	private long total = -1;
	
	public String execute() throws Exception {
		Map<String, Object> session = ActionContext.getContext().getSession();
		String sessionId = getSessionId();
		
		if (scope == SCOPE_ONSALE)
		{
			session.put(STATUS, ONSALE);
			setTotal(detectSales(pageNo, sessionId, session));
		}
		else if (scope == SCOPE_INVENTORY)
		{
			session.put(STATUS, INVENTORY);
			setTotal(detectInventory(1, sessionId, session));
		}
		return SUCCESS;
	}
	
	private long detectSales(int pageNo, String sessionId, Map<String, Object> session) throws Exception
	{
		ItemsOnsaleGetResponse onsales = TaobaoProxy.getOnSales(sessionId, pageNo, PAGE_SIZE, null, null);
		if (onsales.isSuccess())
		{
			long total = onsales.getTotalResults();
			_log.info("onsale.total: " + total);
			session.put(TOTAL, total);
			List<Item> items = onsales.getItems();
			if (items != null)
			{
				detectItems(items, sessionId);
			}
			return total;
		}
		else
		{
			error(onsales);
//			if ("accesscontrol.limited-by-app-access-count".equals(onsales.getSubCode()))
//			{
//				throw new Exception("out-of-band");
//			}
		}
		return -1L;
	}
	
	private long detectInventory(int pageNo, String sessionId, Map<String, Object> session) throws Exception
	{
		ItemsInventoryGetResponse inventory = TaobaoProxy.getInventory(sessionId, pageNo, PAGE_SIZE, null, null, null);
		if (inventory.isSuccess())
		{
			long total = inventory.getTotalResults();
			_log.info("inventory.total: " + total);
			session.put(TOTAL, total);
			List<Item> items = inventory.getItems();
			if (items != null)
			{
				detectItems(items, sessionId);
			}
			return total;
		}
		else
		{
			error(inventory);
//			if ("accesscontrol.limited-by-app-access-count".equals(inventory.getSubCode()))
//			{
//				throw new Exception("out-of-band");
//			}
		}
		return -1L;
	}
	
	private void detectItems(List<Item> items, String sessionId)
	{
		Map<Long,Long> notRepeatCids = new HashMap<Long,Long>();
		List<ItemUpdateResponse> errorItems = getErrorItems();
		for (Item item : items)
		{
			_log.info("checking: " + item.getNumIid() + " - " + item.getTitle());
			if (!notRepeatCids.containsKey(item.getCid()))
			{
				try {
					ItemUpdateResponse rsp = TaobaoProxy.updateItem(sessionId, item.getNumIid());
					if (!rsp.isSuccess())
					{
						_log.info("code: " + rsp.getErrorCode() + " msg: " + rsp.getMsg() + " subCode: " + rsp.getSubCode() + " subMsg: " + rsp.getSubMsg());
						String subCode = rsp.getSubCode();
						if (isRepeatError(subCode))
						{
							_log.info("ignore cid: " + item.getCid());
							notRepeatCids.put(item.getCid(), item.getCid());
						}
						if (subCode != null && !isSystemError(subCode))
						{
							rsp.setItem(item); 
							errorItems.add(rsp);
						}
						if (errorItems.size() >= MAX_ERROR)
						{
							return;
						}
					}
				} catch (ApiException e) {
					_log.log(Level.SEVERE, "", e);
				}
				catch (Exception e) {
					_log.log(Level.SEVERE, "", e);
				}
			}
			increaceProgress();
		}
	}

	public void setPageNo(int pageNo) {
		this.pageNo = pageNo;
	}

	public int getPageNo() {
		return pageNo;
	}

	public void setScope(int scope) {
		this.scope = scope;
	}

	public int getScope() {
		return scope;
	}

	public void setTotal(long total) {
		this.total = total;
	}

	public long getTotal() {
		return total;
	}
	
	public int getPages()
	{
		return PagingResult.getPageCount(total, PAGE_SIZE);
	}
}
